Nombre: Yair Lopez Poveda
Código: 20141578024

1. Aproximaciones para exp(6x)+1.44 exp(2x)- 2.079 exp(4x)- 0.333

Método de bisección con puntos iniciales (-1,0):


In [2]:
import math

def funcion(x):
    return (math.pow(math.e,6*x))+(1.44*math.pow(math.e,2*x))-(2.079*math.pow(math.e,4*x))-(0.333)

def biseccion(intA, intB, errorA, noMaxIter):
        if(funcion(intA)*funcion(intB)<0):
            noIter = 0
            errorTmp = 1
            intTmp = 0
            oldInt = intA
            while(noIter<noMaxIter and errorTmp>errorA and funcion(intTmp)!=0):
                
                intTmp = (intB+intA)/2
                if(funcion(intA)*funcion(intTmp)<0):
                    intB = intTmp
                else:
                    intA = intTmp
                noIter+=1
                errorTmp=abs((intTmp-oldInt)/intTmp)*100
                oldInt = intTmp
                #print('Error: ',errorTmp)
            print('La raíz es: ',intTmp)
            print('F(raiz) es:' ,funcion(intTmp))
            print('Error: ',errorTmp)
            print('No. de iteraciones realizadas: ',noIter)
        else:
            print('En el intervalo dado la función no presenta cambio de signo')
            print('No hay raices que encontrar')
            
biseccion(-1,0,math.pow(10,-6),1000)


La raíz es:  -0.12116142082959414
F(raiz) es: -1.4025947070450684e-11
Error:  7.68662638848817e-07
No. de iteraciones realizadas:  30

Método de regla falsa con puntos iniciales (-1,0):


In [1]:
import math

def funcion(x):
    return (math.pow(math.e,6*x))+(1.44*math.pow(math.e,2*x))-(2.079*math.pow(math.e,4*x))-(0.333)

def reglaFalsa(intA, intB, errorA, noMaxIter):
        if(funcion(intA)*funcion(intB)<0):
            noIter = 0
            errorTmp = 1
            intTmp = 0
            oldInt = intA
            while(noIter<noMaxIter and errorTmp>errorA and funcion(intTmp)!=0):
                intTmp = intB-((funcion(intB)*(intA+intB))/(funcion(intA)-funcion(intB)))
                if(funcion(intA)*funcion(intTmp)<0):
                    intB = intTmp
                else:
                    intA = intTmp
                noIter+=1
                errorTmp=abs((intTmp-oldInt)/intTmp)*100
                oldInt = intTmp
                #print('Error: ',errorTmp)
            print('La raíz es: ',intTmp)
            print('F(raiz) es:' ,funcion(intTmp))
            print('Error: ',errorTmp)
            print('No. de iteraciones realizadas: ',noIter)
        else:
            print('En el intervalo dado la función no presenta cambio de signo')
            print('No hay raices que encontrar')
            
reglaFalsa(-1,0,math.pow(10,-6),1000)


----------------------
0
-0.13880856911963607
-0.13645022566636136
-0.1343426774790894
-0.13247528637155281
-0.1308336482325999
-0.1294007368133094
-0.12815799551297283
-0.12708629246697417
-0.1261666938711975
-0.12538104354140261
-0.12471236012431026
-0.12414507712261451
-0.1236651567011518
-0.12326010846476239
-0.12291894128135229
-0.12263207153190564
-0.12239120610899848
-0.12218921377169283
-0.12201999444508656
-0.12187835283318998
-0.12175988025998247
-0.12166084686313139
-0.12157810501268115
-0.12150900399106018
-0.12145131544402564
-0.12140316880733078
-0.12136299576299553
-0.12132948273089006
-0.12130153041874055
-0.1212782195103167
-0.12125878164934606
-0.12124257496349347
-0.12122906346080478
-0.12121779971563904
-0.12120841033947669
-0.12120058380296779
-0.12119406023865546
-0.12118862290910726
-0.12118409107324012
-0.12118031402503808
-0.12117716611427577
-0.12117454258908726
-0.12117235612584464
-0.12117053393349267
-0.12116901533777197
-0.121167749766181
-0.12116669506744616
-0.12116581611016723
-0.12116508361437
-0.12116447317734864
-0.1211639644615519
-0.12116354051760439
-0.1211631872199874
-0.12116289279668432
-0.12116264743711899
-0.12116244296539437
-0.12116227256795525
-0.12116213056660036
-0.12116201222931942
-0.121161913612628
-0.12116183143018473
-0.12116176294329074
-0.12116170586962595
-0.1211616583072112
-0.12116161867101713
-0.12116158564015608
-0.1211615581138596
-0.12116153517480086
-0.12116151605852135
-0.12116150012795995
-0.12116148685221731
-0.12116147578887249
-0.12116146656922935
-0.12116145888603709
-0.12116145248324665
-0.12116144714747862
-0.12116144270091586
-0.12116143899537138
-0.12116143590735444
-0.12116143333395528
-0.12116143118941401
-0.1211614294022612
-0.12116142791293498
-0.12116142667180464
----------------------
La raíz es:  -0.12116142563750931
F(raiz) es: -1.9918916516203922e-10
Error:  8.536506767693903e-07
No. de iteraciones realizadas:  85

Método de Newton - Raphson con puntos iniciales (-1,-3):


In [18]:
import math

def funcion(x):
    return (math.pow(math.e,6*x))+(1.44*math.pow(math.e,2*x))-(2.079*math.pow(math.e,4*x))-(0.333)

def funcionDeriv(x):
    return (6*math.pow(math.e,6*x))-(8.316*math.pow(math.e,4*x))+(2.88*math.pow(math.e,2*x))

def newtonRaphson(val, errorA, noMaxIter):
    noIter = 0
    errorTmp = 1
    intTmp = 0
    while(noIter<noMaxIter and errorTmp>errorA and funcion(intTmp)!=0):
        valTmp = val-((funcion(val))/(funcionDeriv(val)))
        errorTmp=abs((valTmp-val)/valTmp)*100
        val = valTmp
        noIter+=1
    print('La raíz es: ',valTmp)
    print('F(raiz) es:' ,funcion(valTmp))
    print('Error: ',errorTmp)
    print('No. de iteraciones realizadas: ',noIter)
print('------------------------------------')
print('Valor inicial : -1')
newtonRaphson(-1, math.pow(10,-6),1000)
print('------------------------------------')
print('Valor inicial : -3')
newtonRaphson(-3, math.pow(10,-6),1000)
print('------------------------------------')


------------------------------------
Valor inicial : -1
La raíz es:  -0.12116142046540822
F(raiz) es: -5.551115123125783e-17
Error:  2.1631426280949916e-07
No. de iteraciones realizadas:  12
------------------------------------
Valor inicial : -3
La raíz es:  -0.12116142046539473
F(raiz) es: 3.885780586188048e-16
Error:  4.1635166117760656e-11
No. de iteraciones realizadas:  273
------------------------------------

Método de la secante con puntos iniciales:


In [24]:
import math

def funcion(x):
    return (math.pow(math.e,6*x))+(1.44*math.pow(math.e,2*x))-(2.079*math.pow(math.e,4*x))-(0.333)

def secante(primerVal, segundoVal, errorA, noMaxIter):
    noIter = 0
    errorTmp = 1
    intTmp = 0
    while(noIter<noMaxIter and errorTmp>errorA and funcion(segundoVal)!=0):
        valTmp = segundoVal-((funcion(segundoVal)*(primerVal-segundoVal))/(funcion(primerVal)-funcion(segundoVal)))
        primerVal = segundoVal
        segundoVal = valTmp
        errorTmp=abs((segundoVal-primerVal)/segundoVal)*100
        #print('Noiter: ',noIter, ' primVal:', primerVal,' segunVal:',segundoVal,' error:',errorTmp)
        noIter+=1
    print('La raíz es: ',valTmp)
    print('F(raiz) es:' ,funcion(valTmp))
    print('Error: ',errorTmp)
    print('No. de iteraciones realizadas: ',noIter)
    
print('------------------------------------')
print('Valor inicial : -1 y 0')
secante(-1,0,math.pow(10,-6),1000)
print('------------------------------------')
print('Valor inicial : -3 y -1')
secante(-3,-1,math.pow(10,-6),3000)
print('------------------------------------')


------------------------------------
Valor inicial : -1 y 0
La raíz es:  -0.12116142046540347
F(raiz) es: -5.551115123125783e-17
Error:  2.259971707027581e-08
No. de iteraciones realizadas:  9
------------------------------------
Valor inicial : -3 y -1
La raíz es:  -0.12116142046539927
F(raiz) es: 1.6653345369377348e-16
Error:  5.41291521428627e-10
No. de iteraciones realizadas:  2302
------------------------------------

2. Comparación de resultados del punto anterior


En los resultados del punto anterior se puede ver que el método que más rápido converge de los 4 es el de secante con valores iniciales entre -1 y 0.

Es importante aclarar que los métodos convergen mas rápidamente a la aproximación deseada cuando se toman valores iniciales cercanos a la raíz, esto se demuestra al ver los resultados del método de Newton - Raphson y secante con valor de -3.

Al empezar estos métodos con valores tan distantes de la raíz y ser esta una función polinómica con términos exponenciales se puede ver como necesitan de muchas iteraciones para alcanzar una aproximación aceptable (10^-6)

También se puede observar como el método de regla falsa no es óptimo debido al comportamiento de la función en el área cercana a la raíz, su pendiente no cambia lo suficientemente rápido como para que el método pueda aprovechar su naturaleza

Finalmente vale la pena destacar lo óptimo que son los métodos abiertos sobre los métodos cerrados cuando se toman valores iniciales relativamente cercanos a la raíz. Ambos realizaron menos iteraciones que la mitad de el método de bisecciñon (el mejor de los dos métodos cerrados probados)